package renguanyu.app.codebuilder.view.createcode;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.ObservableMap;
import javafx.geometry.Insets;
import javafx.geometry.NodeOrientation;
import javafx.scene.Node;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.DialogPane;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.SingleSelectionModel;
import javafx.scene.control.TextField;
import javafx.scene.control.ToolBar;
import javafx.stage.Modality;
import renguanyu.app.codebuilder.dao.TemplateDataDao;
import renguanyu.app.codebuilder.model.Template;
import renguanyu.app.codebuilder.util.DaoFactory;
import renguanyu.app.codebuilder.util.FileTool;
import renguanyu.app.codebuilder.view.SaveTemplateBodyView;

public class CreateCodeBottomView extends ToolBar {

    CreateCodeView createCodeView;
    Button createCodeButton = new Button("生成代码");
    Button clearParamButton = new Button("清空参数");

    public CreateCodeBottomView(CreateCodeView createCodeView){
        this.createCodeView = createCodeView;
        initUI();
        initEvent();

    }

    private void initUI() {
        this.setPadding(new Insets(10.0,0.0,10.0,10.0));
        this.setNodeOrientation(NodeOrientation.RIGHT_TO_LEFT);
        this.getItems().addAll(clearParamButton, createCodeButton);
    }

    private void initEvent() {

        createCodeButton.setOnAction(event -> createCode());
        clearParamButton.setOnAction(event -> clearParam());
    }

    private void clearParam() {
        Set<Node> fileDataTextAreaSet = createCodeView.getCreateCodeCenterView().lookupAll(".paramFieldCss");
        fileDataTextAreaSet.forEach(node->{
            TextField paramField = (TextField)node;
            paramField.clear();
        });
        System.out.println(fileDataTextAreaSet);
    }

    private void createCode() {

        CreateCodeCenterView createCodeCenterView = createCodeView.getCreateCodeCenterView();

        CreateCodeTopView createCodeTopView = createCodeView.getCreateCodeTopView();

        SingleSelectionModel<Template> selectionModel = createCodeTopView.getTemplateListCombo().getSelectionModel();
        Template template = selectionModel.getSelectedItem();

        List<String> paramLabelList = new ArrayList<>();
        createCodeCenterView.lookupAll(".paramLabelCss").forEach(node->{
            Label paramLabel = (Label)node;
            paramLabelList.add(paramLabel.getText());
        });

        List<String> paramFieldList = new ArrayList<>();
        createCodeCenterView.lookupAll(".paramFieldCss").forEach(node -> {
            TextField paramField = (TextField)node;
            paramFieldList.add(paramField.getText());
        });

        RadioButton selectedToggle = (RadioButton)createCodeTopView.getSchemeGroup().getSelectedToggle();

        String templateId = template.getId();
        TemplateDataDao templateDataDao = DaoFactory.getTemplateDataDao();
        ObservableList<ObservableMap<String, String>> templateDataList = templateDataDao.query(templateId);

        List<String> newFileDataList = tranFileDataList(paramLabelList, paramFieldList, templateDataList);

        System.out.println(newFileDataList);




        switch (selectedToggle.getText()) {
            case "生成到页面":
                ObservableList<ObservableMap<String, String>> templateDataObList = FXCollections.observableArrayList();
                ObservableMap<String, String> templateObMap = FXCollections.observableHashMap();
                templateObMap.put("TEMP_ID",template.getId());
                templateObMap.put("TEMP_NAME",template.getName());

                for(int i=0;i<newFileDataList.size();i++){
                    ObservableMap<String, String> templateData = templateDataList.get(i);
                    String fileName = templateData.get("F_NAME");
                    String fileData = newFileDataList.get(i);
//                    String newFileData = newFileDataList.get(i);
//                    String paramLabel = paramLabelList.get(i);
                    ObservableMap<String, String> templateDataOb = FXCollections.observableHashMap();
                    templateDataOb.put("F_NAME",fileName);
                    templateDataOb.put("F_DATA",fileData);
                    templateDataObList.add(templateDataOb);
                }
                outToView(templateDataObList, templateObMap);
                break;
            case "生成到硬盘":
                System.out.println(templateDataList);
                System.out.println(newFileDataList);

                List<Map<String,String>> outFileList = new ArrayList<>();
                for(int i=0;i<templateDataList.size();i++){
                    ObservableMap<String, String> templateData = templateDataList.get(i);
                    String fileName = templateData.get("F_NAME");
                    String fileData = newFileDataList.get(i);
                    Map<String,String> map = new HashMap<>();
                    map.put("fileName",fileName);
                    map.put("fileData",fileData);
                    outFileList.add(map);
                }
                System.out.println(outFileList);
                outToDisk(outFileList);

                break;

            default:
                break;
        }

    }

    private void outToDisk(List<Map<String, String>> outFileList) {
        boolean flag = false;
        String outPath = createCodeView.getCreateCodeTopView().getOutPathField().getText();
        String filePrefixString = createCodeView.getCreateCodeTopView().getFilePrefixField().getText();
        for(int i=0;i<outFileList.size();i++){
            Map<String, String> outFile = outFileList.get(i);
            String fileName = outFile.get("fileName");
            String fileData = outFile.get("fileData");
            String newOutPath = tranFileDataPath(fileData,outPath);
            fileName = filePrefixString + fileName;
            flag = FileTool.write(newOutPath, fileName, fileData);
        }
        if(flag){
            Alert alert = new Alert(Alert.AlertType.INFORMATION);
            alert.setTitle("消息提示框");
            alert.setHeaderText("成功");
            alert.show();
        }
        else{
            Alert alert = new Alert(Alert.AlertType.ERROR);
            alert.setTitle("消息提示框");
            alert.setHeaderText("失败");
            alert.show();
        }

    }



    private void outToView(ObservableList<ObservableMap<String, String>> templateDataObList, ObservableMap<String, String> templateObMap) {

        Dialog<ButtonType> saveTemplateDialog = new Dialog<>();
        saveTemplateDialog.setTitle("查看模板");
        DialogPane dialogPane = saveTemplateDialog.getDialogPane();
        Boolean isView = true;
        SaveTemplateBodyView saveTemplateBodyView = new SaveTemplateBodyView(templateObMap,templateDataObList,isView);
        dialogPane.setContent(saveTemplateBodyView);

        dialogPane.getButtonTypes().addAll(ButtonType.CLOSE);
        saveTemplateDialog.initModality(Modality.WINDOW_MODAL);
        saveTemplateDialog.setResizable(true);
        saveTemplateDialog.show();
    }


    /**
     * 转换文件数据列表
     * @param paramLabelList 标签，用于定位模板的点
     * @param paramFieldList 值，用于替换点上的值
     * @param templateDataList 待转换的数据
     * @return 转换后的值
     */
    private List<String> tranFileDataList(List<String> paramLabelList, List<String> paramFieldList, ObservableList<ObservableMap<String, String>> templateDataList) {
        List<String> newfileDataList = new ArrayList<>();
        for(int i=0;i<templateDataList.size();i++){
            ObservableMap<String, String> templateData = templateDataList.get(i);
            String oldFileData = templateData.get("F_DATA");
            String newFileData = null ;
            for(int j=0;j<paramLabelList.size();j++){
                String label = paramLabelList.get(j);
                String field = paramFieldList.get(j);
                oldFileData = oldFileData.replaceAll("\\$\\{("+label+")\\}", field);
            }
            newfileDataList.add(oldFileData);
        }
        return newfileDataList;
    }

    /**
     * 把Java文件中的包名转换成文件路径，并和输出路径拼接，组成完整的文件输出路径，
     * @param fileData
     * @param outPath
     * @return
     */
    private String tranFileDataPath(String fileData, String outPath) {
        String regex = "package(.*?);.*?\n.*?";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(fileData); // 获取 matcher 对象
        while(m.find()) {
            String packageName = m.group(1);
            outPath = outPath+tranPointToSep(packageName);//把.转换成/

        }
        return outPath;
    }

    /**
     * 把包名转换成操作系统的路径
     * @param packageName 包名
     * @return
     */
    private String tranPointToSep(String packageName) {
        packageName = packageName.trim();
        packageName = packageName.replace(".",File.separator);
        packageName = File.separator+packageName;
        return packageName;
    }
}
